package cn.maihe.elg.operation.centers.fuzhou.handler.service;

import cn.maihe.elg.operation.centers.fuzhou.config.FZMakeInfoConfig;
import cn.maihe.elg.operation.centers.fuzhou.dto.FZBaseRespDTO;
import cn.maihe.elg.operation.centers.fuzhou.dto.handler.FZClaimApplyReqDTO;
import cn.maihe.elg.operation.centers.fuzhou.handler.FZCenterTradeService;
import cn.maihe.elg.operation.centers.supports.CenterTradeContext;
import cn.maihe.elg.operation.centers.supports.annotation.CenterTradeService;
import cn.maihe.elg.operation.model.enums.*;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeInstitutionDO;
import cn.maihe.elg.operation.repository.entity.ProjectInfoDO;
import cn.maihe.elg.operation.repository.entity.RefundOrderInfoDO;
import cn.maihe.elg.operation.service.business.InstitutionService;
import cn.maihe.elg.operation.service.business.ProjectInfoService;
import cn.maihe.elg.operation.service.guarantee.GuaranteeService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.service.order.ApplyOrderInfoService;
import cn.maihe.elg.operation.service.order.RefundOrderInfoService;
import cn.maihe.elg.operation.utils.IdGenerate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.Date;

/**
 * @Description 保函理赔申请
 * @Author caixh
 * @Date 2022/3/30.
 */
@CenterTradeService(
        provider = CenterProviderEnum.ESB_FUZHOU,
        centerNo = CenterNoEnum.FUZHOU,
        tradeType = TradeType.lstClaim,
        reqClass = FZClaimApplyReqDTO.class,
        respClass = FZBaseRespDTO.class
)
@Slf4j
public class FZClaimApplyService extends FZCenterTradeService<FZClaimApplyReqDTO, FZBaseRespDTO> {

    @Resource
    ApplyOrderInfoService applyOrderInfoService;
    @Resource
    AcceptOrderInfoService acceptOrderInfoService;
    @Resource
    RefundOrderInfoService refundOrderInfoService;
    @Resource
    ProjectInfoService projectInfoService;
    @Resource
    private InstitutionService institutionService;
    @Resource
    GuaranteeService guaranteeService;

    public FZClaimApplyService(FZMakeInfoConfig centerInfosConfig) {
        super(centerInfosConfig);
    }


    /**
     * 具体业务处理
     *
     * @param context
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FZBaseRespDTO processService(CenterTradeContext<FZClaimApplyReqDTO, FZBaseRespDTO> context) {

        FZClaimApplyReqDTO req = context.getReq();
        Long centerId = context.getCenterId();
        Long orgId = context.getOrgId();
        String revokeNo = req.getPolicyNo();

        AcceptOrderInfoDO orderInfo = acceptOrderInfoService.getByGuaranteeNo(centerId, orgId, revokeNo);
        if (orderInfo == null) {
            return FZBaseRespDTO.error("查无此投保申请记录");
        }

//        GuaranteeDO guaranteeDO = guaranteeService.getGuaranteeByGuaranteeNo(orderInfo.getGuaranteeNo());
//        if (guaranteeDO == null) {
//            return HyMakeBaseRespDTO.error("查无此保函记录");
//        }

        if (orderInfo.getStatus() == AcceptOrderStatus.FINISH.getStatus()) {
            return FZBaseRespDTO.error("保函已完成，不能理赔申请");
        }
        if (orderInfo.getStatus() == AcceptOrderStatus.CANCEL.getStatus()) {
            return FZBaseRespDTO.error("保函已取消，不能理赔申请");
        }
        if (orderInfo.getStatus() != AcceptOrderStatus.HAS_OUT_GUARANTEE.getStatus()) {
            return FZBaseRespDTO.error("已出函状态才能发起理赔");
        }

        ClaimsStatus claimsStatus = ClaimsStatus.resolve(orderInfo.getClaimsStatus());
        if (claimsStatus == ClaimsStatus.SUCCESS) {
            return FZBaseRespDTO.error("理赔处理完成[" + claimsStatus + "]," + orderInfo.getClaimsRemark());
        }
        if (claimsStatus == ClaimsStatus.PROCESSING) {
            return FZBaseRespDTO.error("理赔处理中,不能重复发起理赔");
        }

        ProjectInfoDO projectInfoDO = projectInfoService.selectById(orderInfo.getProjectId());
        GuaranteeInstitutionDO institutionDO = institutionService.selectById(orderInfo.getInstitutionId());

        AcceptOrderInfoDO updateOrderInfo = AcceptOrderInfoDO.builder().id(orderInfo.getId())
                .claimsStatus(ClaimsStatus.PROCESSING.getStatus()).claimsRemark(req.getClaimReason()).build();
        acceptOrderInfoService.updateById(updateOrderInfo);

        if( claimsStatus == ClaimsStatus.FAILURE ){
            RefundOrderInfoDO curDo = refundOrderInfoService.getByGuaranteeNo(revokeNo);


            curDo.setRemark(req.getClaimReason());
            curDo.setApplyUserName(req.getClaimName());
            curDo.setApplyUserPhone(req.getClaimPhone());
            curDo.setStatus(RefundOrderStatus.UNREFUND.getStatus());

            refundOrderInfoService.updateById(curDo);
        }else {
            //配合后管进行 审核操作，审核操作中需要同步到 accepInfo中的理赔最终状态
            RefundOrderInfoDO curDo = RefundOrderInfoDO.builder()
                    .id(IdGenerate.getId()).centerId(context.getCenterId())
                    .orgId(context.getOrgId()).guaranteeNo(req.getPolicyNo())
                    .centerOrderId(orderInfo.getCenterOrderId()).acceptOrderNo(orderInfo.getAcceptOrderNo())
                    .applyOrderNo(orderInfo.getApplyOrderNo())
                    .guaranteeType(orderInfo.getGuaranteeType()).guaranteeCategory(orderInfo.getGuaranteeCategory())
                    .guaranteeFee(orderInfo.getGuaranteeFee()).projectId(orderInfo.getProjectId()).projectName(projectInfoDO.getProjectName())
                    .sectionName(orderInfo.getSectionName())
                    .bidCustomerId(orderInfo.getBidCustomerId()).bidCustomerName(orderInfo.getBidCustomerName())
                    .bidIndate(orderInfo.getBidIndate())
                    .bidBond(projectInfoDO.getBidBond())
                    .institutionId(orderInfo.getInstitutionId())
                    .institutionName(institutionDO.getGuarantorName())
                    .attachmentId(orderInfo.getAttachmentId()).remark(req.getClaimReason())
                    .inviteCode(orderInfo.getInviteCode())
                    .applyUserName(req.getClaimName()).applyUserPhone(req.getClaimPhone())
                    .gmtCreate(Date.from(Instant.now())).gmtModified(Date.from(Instant.now())).userCreate("接口申请")
                    .status(RefundOrderStatus.UNREFUND.getStatus())
                    .build();
            refundOrderInfoService.insert(curDo);
        }

        return FZBaseRespDTO.success("理赔申请已受理,请耐心等待审核结果通知");
    }
}
